﻿Imports System.Drawing
Imports System.Windows.Forms
Imports AvianWaves.AvianPlay.Language

Public Class ControlEditor
  Private _surfaces As List(Of ControlSurface) = Nothing
  Private _dpiFactor As Single = 0.0F
  Private _smallDPIFactor As Single = 0.0F
  Private _curSurface As Integer = 0
  Private _curButton As ControlButton = Nothing
  Private _moveRow As ControlRow = Nothing
  Private _mode As EditMode = EditMode.Normal

  Private Enum EditMode
    Normal
    ChangeSurface
    AddRow
    RemoveRow
    RowOrder1
    RowOrder2
    EditButton
  End Enum

  Public Sub New()
    Me.InitializeComponent()
    Me._dpiFactor = Me.AutoScaleDimensions.Height / 192.0F
    Me._smallDPIFactor = Me._dpiFactor / 2.0F

    ' Reset button sizes based on actual device screen height
    Dim sep As Integer = 5 * Me._dpiFactor
    Me.WP7ButtonChangeSurface.Height = (Me.PanelEditor.Height - (5 * sep)) / 5
    Me.WP7ButtonChangeSurface.Top = 0
    Me.WP7ButtonRemoveScene.Height = Me.WP7ButtonChangeSurface.Height
    Me.WP7ButtonRemoveScene.Top = WP7ButtonChangeSurface.Bottom + sep
    Me.WP7ButtonAddRow.Height = Me.WP7ButtonChangeSurface.Height
    Me.WP7ButtonAddRow.Top = Me.WP7ButtonRemoveScene.Bottom + sep
    Me.WP7ButtonRemoveRow.Height = Me.WP7ButtonChangeSurface.Height
    Me.WP7ButtonRemoveRow.Top = Me.WP7ButtonAddRow.Bottom + sep
    Me.WP7ButtonRowOrder.Height = Me.WP7ButtonChangeSurface.Height
    Me.WP7ButtonRowOrder.Top = Me.WP7ButtonRemoveRow.Bottom + sep

    ' Set language strings
    Me.WP7ButtonChangeSurface.Text = GetLanguageString("ControlButtonSelectSurfaceScene")
    Me.WP7ButtonRemoveScene.Text = GetLanguageString("ControlButtonRemoveScene")
    Me.WP7ButtonAddRow.Text = GetLanguageString("ControlButtonAddRow")
    Me.WP7ButtonRemoveRow.Text = GetLanguageString("ControlButtonRemoveRow")
    Me.WP7ButtonRowOrder.Text = GetLanguageString("ControlButtonRowOrder")
  End Sub

  Public Overrides Property BackColor() As System.Drawing.Color
    Get
      Return MyBase.BackColor
    End Get
    Set(ByVal value As System.Drawing.Color)
      MyBase.BackColor = value
      Me.PanelEditor.BackColor = value
      Me.PanelTop.BackColor = value
      Me.PanelControls.BackColor = value
      Me.LabelTop.BackColor = value
      Me.WP7ButtonChangeSurface.BackColor = value
      Me.WP7ButtonAddRow.BackColor = value
      Me.WP7ButtonRemoveRow.BackColor = value
      Me.WP7ButtonRowOrder.BackColor = value
      Me.SelectSurfaceAndScene1.BackColor = value
      Me.SelectRowCount1.BackColor = value
      Me.SelectFunction1.BackColor = value
    End Set
  End Property

  Public Property BackColorTextbox() As System.Drawing.Color
    Get
      Return Me.SelectSurfaceAndScene1.BackColorTextbox
    End Get
    Set(ByVal value As System.Drawing.Color)
      Me.SelectSurfaceAndScene1.BackColorTextbox = value
      Me.SelectRowCount1.BackColorTextbox = value
      Me.SelectFunction1.BackColorTextbox = value
    End Set
  End Property

  Public Overrides Property ForeColor() As System.Drawing.Color
    Get
      Return MyBase.ForeColor
    End Get
    Set(ByVal value As System.Drawing.Color)
      MyBase.ForeColor = value
      Me.LabelTop.ForeColor = value
      Me.WP7ButtonChangeSurface.ForeColor = value
      Me.WP7ButtonAddRow.ForeColor = value
      Me.WP7ButtonRemoveRow.ForeColor = value
      Me.WP7ButtonRowOrder.ForeColor = value
      Me.SelectSurfaceAndScene1.ForeColor = value
      Me.SelectRowCount1.ForeColor = value
      Me.SelectFunction1.ForeColor = value
    End Set
  End Property

  Public Property InactiveForeColor() As Color
    Get
      Return Me.WP7ButtonChangeSurface.InactiveForeColor
    End Get
    Set(ByVal value As Color)
      Me.WP7ButtonChangeSurface.InactiveForeColor = value
      Me.WP7ButtonAddRow.InactiveForeColor = value
      Me.WP7ButtonRemoveRow.InactiveForeColor = value
      Me.WP7ButtonRowOrder.InactiveForeColor = value
    End Set
  End Property

  Public Property Surfaces() As List(Of ControlSurface)
    Get
      Return Me._surfaces
    End Get
    Set(ByVal value As List(Of ControlSurface))
      ' remove all old control surfaces (and clean out the insides)
      If Me._surfaces IsNot Nothing Then
        For Each sc In Me._surfaces
          sc.Clear()
        Next
      End If

      ' Deep copy the entire given control surface
      Me._surfaces = New List(Of ControlSurface)
      For Each sc As ControlSurface In value
        Me._surfaces.Add(sc.Copy)
      Next

      ' Set all buttons to active/enabled ("able to be pressed" state)
      For Each su As ControlSurface In Me._surfaces
        For Each sc As ControlScene In su.Scenes
          For Each ro As ControlRow In sc.Rows
            For Each bt As ControlButton In ro.Buttons
              bt.IsActive = True
            Next
          Next
        Next
      Next

      ' Reset all index to default
      Me._curSurface = 0
      Me._surfaces(0).CurrentSceneIndex = 0
      Me.SetNormalLabel()
    End Set
  End Property

  Private Sub PanelControls_Paint(ByVal sender As Object, ByVal e As PaintEventArgs) Handles PanelControls.Paint
    Static Dim bufWidth As Integer = 0
    Static Dim bufHeight As Integer = 0
    Static Dim buffer As Bitmap = Nothing

    If Me._surfaces IsNot Nothing Then
      If buffer Is Nothing OrElse Me.PanelControls.Width <> bufWidth OrElse Me.PanelControls.Height <> bufHeight Then
        bufWidth = Me.PanelControls.Width
        bufHeight = Me.PanelControls.Height

        If buffer IsNot Nothing Then buffer.Dispose()

        buffer = New Bitmap(bufWidth, bufHeight)
      End If

      Dim g As Graphics = Graphics.FromImage(buffer)
      g.FillRectangle(New SolidBrush(Me.BackColor), 0, 0, bufWidth, bufHeight)

      Me._surfaces(Me._curSurface).DrawSurface(g, New Rectangle(0, 0, Me.PanelControls.Width, Me.PanelControls.Height), Me._smallDPIFactor, Not (Me._mode = EditMode.Normal), (Me._mode = EditMode.Normal))

      g.Dispose()

      e.Graphics.DrawImage(buffer, 0, 0)
    End If
  End Sub

  Private Sub PanelControls_MouseUp(ByVal sender As System.Object, ByVal e As MouseEventArgs) Handles PanelControls.MouseUp
    If Me._surfaces IsNot Nothing Then
      Select Me._mode
        Case EditMode.Normal
          Dim fb As ControlButton = Nothing
          For Each r As ControlRow In Me._surfaces(Me._curSurface).CurrentScene.Rows
            For Each b As ControlButton In r.Buttons
              If b.ButtonRectangle.Contains(e.X, e.Y) Then
                fb = b
                Exit For
              End If
            Next
            If fb IsNot Nothing Then
              Exit For
            End If
          Next

          If fb IsNot Nothing Then
            Me.ChangeButton(fb)
          End If

        Case EditMode.RemoveRow
          Dim row As ControlRow = Nothing

          For Each r As ControlRow In Me._surfaces(Me._curSurface).CurrentScene.Rows
            If r.LastRectangle.Contains(e.X, e.Y) Then
              row = r
              Exit For
            End If
          Next

          If row IsNot Nothing Then
            Me._surfaces(Me._curSurface).CurrentScene.Rows.Remove(row)
            Me.PanelControls.Invalidate()
          End If

        Case EditMode.RowOrder1
          For Each r As ControlRow In Me._surfaces(Me._curSurface).CurrentScene.Rows
            If r.LastRectangle.Contains(e.X, e.Y) Then
              Me._moveRow = r
              Exit For
            End If
          Next

          If Me._moveRow IsNot Nothing Then
            Me._mode = EditMode.RowOrder2
            Me.LabelTop.Text = GetLanguageString("ControlMoveRow2")
          End If

        Case EditMode.RowOrder2
          Dim destRow As ControlRow = Nothing

          For Each r As ControlRow In Me._surfaces(Me._curSurface).CurrentScene.Rows
            If r.LastRectangle.Contains(e.X, e.Y) Then
              destRow = r
              Exit For
            End If
          Next

          If destRow IsNot Nothing Then
            If destRow IsNot Me._moveRow Then
              Dim dest As Integer = Me._surfaces(Me._curSurface).CurrentScene.Rows.IndexOf(destRow)
              Me._surfaces(Me._curSurface).CurrentScene.Rows.Remove(Me._moveRow)
              Me._surfaces(Me._curSurface).CurrentScene.Rows.Insert(dest, Me._moveRow)
              Me._moveRow = Nothing
              Me.PanelControls.Invalidate()
            End If
            Me._mode = EditMode.RowOrder1
            Me.LabelTop.Text = GetLanguageString("ControlMoveRow1")
          End If
      End Select
    End If
  End Sub

  Private Sub MenuItemCancel_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MenuItemCancel.Click
    If Me._mode = EditMode.Normal Then
      Me.DialogResult = Windows.Forms.DialogResult.Cancel
      Me.Close()
    Else
      Me.RestoreNormalMode()
    End If
  End Sub

  Private Sub MenuItemOK_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MenuItemOK.Click
    Select Case Me._mode
      Case EditMode.Normal
        Windows.Forms.Cursor.Current = Cursors.WaitCursor
        Configuration.SaveSurfacesCollectionToINI(Me._surfaces, Settings.INIControlsPath)
        Windows.Forms.Cursor.Current = Cursors.Default
        Me.DialogResult = Windows.Forms.DialogResult.OK
        Me.Close()
      Case EditMode.AddRow
        Me._surfaces(Me._curSurface).CurrentScene.Rows.Add(New ControlRow(Me.SelectRowCount1.ButtonCount))
        Me.RestoreNormalMode()
      Case EditMode.RemoveRow, EditMode.RowOrder1, EditMode.RowOrder2
        Me.RestoreNormalMode()
      Case EditMode.ChangeSurface
        Me._curSurface = Me.SelectSurfaceAndScene1.Surface
        If Me.SelectSurfaceAndScene1.Scene >= Me._surfaces(Me._curSurface).Scenes.Count Then
          Dim s As New ControlScene
          Me._surfaces(Me._curSurface).Scenes.Add(s)
          Me._surfaces(Me._curSurface).CurrentSceneIndex = Me._surfaces(Me._curSurface).Scenes.Count - 1
          Me.SelectSurfaceAndScene1.RefreshSurfaceScenes()
        Else
          Me._surfaces(Me._curSurface).CurrentSceneIndex = Me.SelectSurfaceAndScene1.Scene
        End If
        Me.RestoreNormalMode()
      Case EditMode.EditButton
        Me._mode = EditMode.Normal
        Me._curButton.SetButton(Me.SelectFunction1.SelectedFunction, Me.SelectFunction1.SelectedParameter)
        Me._curButton.IsActive = True
        Me.RestoreNormalMode()
    End Select
  End Sub

  Private Sub SetFalseEnabledStates()
    Me.WP7ButtonAddRow.Enabled = False
    Me.WP7ButtonChangeSurface.Enabled = False
    Me.WP7ButtonRemoveRow.Enabled = False
    Me.WP7ButtonRemoveScene.Enabled = False
    Me.WP7ButtonRowOrder.Enabled = False
  End Sub

  Private Sub RestoreNormalMode()
    Me._mode = EditMode.Normal
    Me.SetNormalLabel()
    Me.SelectSurfaceAndScene1.Enabled = False
    Me.SelectSurfaceAndScene1.Visible = False
    Me.SelectRowCount1.Enabled = False
    Me.SelectRowCount1.Visible = False
    Me.SelectFunction1.Enabled = False
    Me.SelectFunction1.Visible = False
    Me.WP7ButtonAddRow.Enabled = True
    Me.WP7ButtonChangeSurface.Enabled = True
    Me.WP7ButtonRemoveRow.Enabled = True
    Me.WP7ButtonRemoveScene.Enabled = Me.CanRemoveScene
    Me.WP7ButtonRowOrder.Enabled = True
    Me.MenuItemOK.Enabled = True
    Me.MenuItemCancel.Enabled = True
    Me.PanelControls.Invalidate()
  End Sub

  Private Sub SetNormalLabel()
    If Me._surfaces IsNot Nothing Then
      Dim colstr As String = String.Empty
      If Me._curSurface = 0 Then
        colstr = GetLanguageString("BottomMenuMusic")
      ElseIf Me._curSurface = 1 Then
        colstr = GetLanguageString("BottomMenuPodcast")
      Else
        colstr = GetLanguageString("BottomMenuRadio")
      End If

      Me.LabelTop.Text = GetLanguageString("Surface") & ": " & colstr & ", " & GetLanguageString("Scene") & ": " & Me._surfaces(Me._curSurface).CurrentSceneIndex.ToString
    End If
  End Sub

  Public Sub SelectSurfaceAndScene1_SceneCount(ByVal surface As Integer, ByRef currentScene As Integer, ByRef sceneCount As Integer) Handles SelectSurfaceAndScene1.SceneCount
    If surface >= 0 AndAlso surface < Me._surfaces.Count Then
      sceneCount = Me._surfaces(surface).Scenes.Count
      currentScene = Me._surfaces(surface).CurrentSceneIndex
      If currentScene < 0 Then currentScene = 0
    End If
  End Sub

  Private Sub WP7ButtonChangeSurface_MouseUp(ByVal sender As System.Object, ByVal e As MouseEventArgs) Handles WP7ButtonChangeSurface.MouseUp
    If Me.WP7ButtonChangeSurface.Enabled Then
      If Me._mode = EditMode.Normal Then
        Me._mode = EditMode.ChangeSurface
        Me.SetFalseEnabledStates()
        Me.SelectSurfaceAndScene1.Surface = Me._curSurface
        Me.SelectSurfaceAndScene1.Scene = Me._surfaces(Me._curSurface).CurrentSceneIndex
        Me.SelectSurfaceAndScene1.Enabled = True
        Me.SelectSurfaceAndScene1.Visible = True
      End If
      Me.SetNormalLabel()
      Me.PanelControls.Invalidate()
    End If
  End Sub

  Private Sub WP7ButtonRemoveScene_MouseUp(ByVal sender As System.Object, ByVal e As MouseEventArgs) Handles WP7ButtonRemoveScene.MouseUp
    If Me.WP7ButtonRemoveScene.Enabled AndAlso Me._surfaces IsNot Nothing Then
      If MessageBox.Show(GetLanguageString("ControlDeleteSceneAreYouSure"), "Avian Play", MessageBoxButtons.YesNo, MessageBoxIcon.Question, MessageBoxDefaultButton.Button2) = Windows.Forms.DialogResult.Yes Then
        Dim idx As Integer = Me._surfaces(Me._curSurface).CurrentSceneIndex
        Me._surfaces(Me._curSurface).Scenes.Remove(Me._surfaces(Me._curSurface).CurrentScene)
        While idx >= Me._surfaces(Me._curSurface).Scenes.Count AndAlso idx > 0
          idx -= 1
        End While
        Me._surfaces(Me._curSurface).CurrentSceneIndex = idx
        Me.WP7ButtonRemoveScene.Enabled = Me.CanRemoveScene
        Me.SelectSurfaceAndScene1.RefreshSurfaceScenes()
        Me.SetNormalLabel()
        Me.PanelControls.Refresh()
      End If
    End If
  End Sub

  Private Sub WP7ButtonAddRow_MouseUp(ByVal sender As System.Object, ByVal e As MouseEventArgs) Handles WP7ButtonAddRow.MouseUp
    If Me.WP7ButtonAddRow.Enabled AndAlso Me._surfaces IsNot Nothing Then
      If Me._mode = EditMode.Normal Then
        Me._mode = EditMode.AddRow
        Me.SetFalseEnabledStates()
        Me.SelectRowCount1.Enabled = True
        Me.SelectRowCount1.Visible = True
        Me.LabelTop.Text = GetLanguageString("ControlButtonAddRow")
      End If
      Me.PanelControls.Invalidate()
    End If
  End Sub

  Private Sub WP7ButtonRemoveRow_MouseUp(ByVal sender As System.Object, ByVal e As MouseEventArgs) Handles WP7ButtonRemoveRow.MouseUp
    If WP7ButtonRemoveRow.Enabled Then
      If Me._mode = EditMode.Normal Then
        Me._mode = EditMode.RemoveRow
        Me.SetFalseEnabledStates()
        Me.MenuItemCancel.Enabled = False
        Me.LabelTop.Text = GetLanguageString("ControlRemoveRowTitle")
      End If
      Me.PanelControls.Invalidate()
    End If
  End Sub

  Private Sub WP7ButtonRowOrder_MouseUp(ByVal sender As System.Object, ByVal e As MouseEventArgs) Handles WP7ButtonRowOrder.MouseUp
    If WP7ButtonRowOrder.Enabled Then
      If Me._mode = EditMode.Normal Then
        Me._mode = EditMode.RowOrder1
        Me.SetFalseEnabledStates()
        Me.MenuItemCancel.Enabled = False
        Me.LabelTop.Text = GetLanguageString("ControlMoveRow1")
      End If
      Me.PanelControls.Invalidate()
    End If
  End Sub

  Private Function CanRemoveScene() As Boolean
    If Me._surfaces IsNot Nothing Then
      Return (Me._surfaces(Me._curSurface).Scenes.Count > 1)
    End If
    Return False
  End Function

  Private Sub ChangeButton(ByRef bt As ControlButton)
    Me._mode = EditMode.EditButton
    Me._curButton = bt
    Me.SelectFunction1.SelectedFunction = bt.FunctionIndex
    Me.SelectFunction1.SelectedParameter = bt.FunctionParameter
    Me.SelectFunction1.Enabled = True
    Me.SelectFunction1.Visible = True
    Me.WP7ButtonAddRow.Enabled = False
    Me.WP7ButtonChangeSurface.Enabled = False
    Me.WP7ButtonRemoveRow.Enabled = False
    Me.WP7ButtonRemoveScene.Enabled = False
    Me.WP7ButtonRowOrder.Enabled = False
  End Sub
End Class
